﻿#region Using Directives

    using System;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;

    using Csla;
    using Csla.Data;
    using Csla.Server;
    using Csla.Reflection;

    using MarketPulse.BusinessLogic.Core;
    using MarketPulse.DataAccess;
    using MarketPulse.Reporting.Core;
    using MarketPulse.Reporting.Core.Criteria;

#endregion

namespace MarketPulse.DataAccess.Factory
{
    /// <summary>
    /// A factory class for producing ReportingQuestionInfoLists
    /// </summary>
    public class ReportingQuestionFactory : ObjectFactory
    {
        #region Methods

            #region FetchMethods

                #region ReportingQuestionInfoList

                    /// <summary>
                    /// Retrieves a ReportingQuestionInfoList based on the supplied criteria
                    /// </summary>
                    /// <param name="criteria">The client GUID and Visit Version ID</param>
                    /// <returns>The populated ReportingQuestionInfoList</returns>
                    public ReportingQuestionInfoList FetchInfoList(ClientGUIDAndVisitIDAndVisitVersionIDCriteria criteria)
                    {
                        try
                        {
                            using (var manager = ContextManager<DataContextObjects.Reporting.MUMReporting_dev>.GetManager(Database.ReportingSystem))
                            {
                                // Create an empty instance of ReportingQuestionInfoList to be returned.
                                var reportingQuestionInfoList = (ReportingQuestionInfoList)MethodCaller.CreateInstance(typeof(ReportingQuestionInfoList));

                                // Mark the new instance of ReportingQuestionInfoList as writable as it inherits from MarketPulseReadOnlyBase
                                SetIsReadOnly(reportingQuestionInfoList, false);

                                // Select the resultset from the database.
                                var reportingQuestionInfoSelect = manager.DataContext.UspReportingQuestionSelectByClientGUIDAndVisitIDAndVisitVersionID(criteria.ClientGUID, criteria.VisitID, criteria.VisitVersionID);

                                // Iterate over each row and append the object to the ReportingQuestionInfoList
                                foreach (var result in reportingQuestionInfoSelect)
                                {
                                    // Create an empty instance of ReportingQuestionInfo to be appended to the ReportingQuestionInfoList
                                    var reportingQuestionInfo = (ReportingQuestionInfo)MethodCaller.CreateInstance(typeof(ReportingQuestionInfo));

                                    // Load the base properties
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.GUIDProperty, result.QuestionGUID.Value);

                                    // TODO: What do we do about these properties on a Reporting object?
                                    /*
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.ObsoleteProperty, result.Obsolete.Value);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.InsertDateTimeProperty, (SmartDate)result.InsertDateTime);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.UpdateDateTimeProperty, (SmartDate)result.UpdateDateTime);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                                    */

                                    // Load the ReportingQuestionInfo specific properties
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.IDProperty, result.QuestionID.Value);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.ClientGUIDProperty, criteria.ClientGUID);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.VisitGUIDProperty, result.VisitGUID.Value);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.CategoryGUIDProperty, result.CategoryGUID.Value);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.CategoryOrderProperty, result.CategoryOrder.Value);
                                    //LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.CategoryTitleProperty, result.CategoryTitle);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.DisplayNumberProperty, result.DisplayNumber);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.NumberProperty, result.QuestionNumber);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.TextProperty, result.QuestionText);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.TypeProperty, result.QuestionType);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.StandardProperty, result.QuestionStandard);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.ShopperNoteProperty, result.ShopperNote);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.QANoteProperty, result.QANote);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.PossibleScoreProperty, result.PossibleScore.Value);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.ActualScoreProperty, result.ActualScore.Value);
                                    LoadProperty(reportingQuestionInfo, ReportingQuestionInfo.TransferDateTimeProperty, result.TransferDateTime);

                                    // Mark the ReportingQuestionInfo object as old so CSLA knows it has changed
                                    MarkOld(reportingQuestionInfo);

                                    // Add the ReportingQuestionInfo object to the ReportingQuestionInfoList collection
                                    reportingQuestionInfoList.Add(reportingQuestionInfo);
                                }

                                // Mark the new instance of ReportingQuestionInfoList as read-only before returning it to the client
                                SetIsReadOnly(reportingQuestionInfoList, true);

                                // Mark the ReportingQuestionInfoList object as old so CSLA knows it has changed
                                MarkOld(reportingQuestionInfoList);

                                // Return the newly populated ReportingQuestionInfoList
                                return reportingQuestionInfoList;
                            }
                        }
                        catch (InvalidOperationException ioe)
                        {
                            //TODO log exception appropriately before re throwing
                            throw ioe;
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }

                #endregion

            #endregion

        #endregion

    }
}
